package com.woniu.filter;


import com.woniu.exception.gateway.GatewayException;


import com.woniu.utils.JwtUtil;

import io.jsonwebtoken.Claims;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.SneakyThrows;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.cloud.gateway.filter.GatewayFilterChain;
import org.springframework.cloud.gateway.filter.GlobalFilter;
import org.springframework.context.annotation.Bean;
import org.springframework.stereotype.Component;
import org.springframework.util.AntPathMatcher;
import org.springframework.web.server.ServerWebExchange;
import reactor.core.publisher.Mono;

import java.util.Date;
import java.util.HashMap;
import java.util.List;

@Component
public class AuthenticationFilter implements GlobalFilter {

    @Autowired
    private UrlPropertiles urlProperties;

    @Bean
    public AntPathMatcher antPathMatcher() {
        return new AntPathMatcher();
    }

    @Autowired
    private AntPathMatcher apm;



    @SneakyThrows
    @Override
    public Mono<Void> filter(ServerWebExchange exchange, GatewayFilterChain chain) {
        System.out.println("--------------认证--------------");
        //放行
        String url = exchange.getRequest().getPath().toString();
        System.out.println("url:" + url);
        for (String baseUrl : urlProperties.getUrls()) {
            if (apm.match(baseUrl, url)) return chain.filter(exchange);
        }
        //不能放行，需要认证
        List<String> values = exchange.getRequest().getHeaders().get("token");
        if (values == null || values.size() <= 0) {
            throw new GatewayException("未登录", 401);
        }
        String token = values.get(0);
        if (url.endsWith(".api")) {
            try {
                JwtUtil.parseToken(token);
            } catch (Exception e) {
                e.printStackTrace();
                throw new GatewayException("未登录", 401);
            }
        } else {
            try {
                JwtUtil.parseToken(token);
            } catch (Exception e) {
                e.printStackTrace();
                throw new GatewayException("未登录", 401);
            }
        }
        //通过


        try {
            Claims claims = JwtUtil.parseToken(token);
            if ((claims.getExpiration().getTime() - new Date().getTime()) / 1000 / 60 < 30) {
                throw new ExpiredJwtException(null, claims, "Token时间不足");
            }
        } catch (ExpiredJwtException e) {
            Claims claims = JwtUtil.parseToken(token);
            //判断是否还剩十分钟
            if ((claims.getExpiration().getTime() - new Date().getTime()) / 1000 / 60 < 10) {
                throw e;
            }


            HashMap<String, Object> refre = new HashMap<>();
            String roleId = claims.get("roleId").toString().toString();
            if (roleId.equals("3") || roleId.equals("5")) {
//                 admin
//                "adminId": 1,
//                "adminName": "admin",
//                "roleId": 5,
//                "roleName": "超级管理员"
                refre.put("adminId", claims.get("adminId"));
                refre.put("adminName", claims.get("adminName"));
                refre.put("roleId", claims.get("roleId"));
                refre.put("roleName", claims.get("roleName"));
            } else {
                //user
//                "userId": 5,
//                "userImg": null,
//                "userName": "1",
//                "userPhone": "13888888888",
//                "roleId": 4,
//                "roleName": "维修员"
                refre.put("userId", claims.get("userId"));
                refre.put("userImg", claims.get("userImg"));
                refre.put("userName", claims.get("userName"));
                refre.put("userPhone", claims.get("userPhone"));
                refre.put("roleId", claims.get("roleId"));
                refre.put("roleName", claims.get("roleName"));
            }

            String newRefreShToken = JwtUtil.createToken(refre, 600 * 12);

            //token返回前端
            exchange.getRequest().getHeaders().set("token", newRefreShToken);
            exchange.getRequest().getHeaders().set("Access-Control-Expose-Headers", "token");
        }

        return chain.filter(exchange);
    }

}















